#pragma once

#include "mission.h"
#include "mission_manager.h"
#include "userAPI.h"
#include "move_mission.h"
#include "params.h"

using namespace AI9;

class occupy_empty_mission : public move_mission
{
public:
	class occupy_completed_event : public mission_completed_event
	{
	public:
		occupy_completed_event(mission *m, bool actioned, bool succeeded) : mission_completed_event(m, actioned) 
		{
			actioned_state = actioned;
			result = succeeded;
		}

		virtual std::string get_type() { return "occupy_completed_event";}
		bool actioned_state;
		bool result;
	};

	occupy_empty_mission(mission *parent_mission, const gtype_list &troop, Position target) : move_mission(parent_mission, troop, target) 
	{
		/*
			occupy_empty_mission only handles the case that one general moves to one target
		 */
		m_target = target;
	}

	virtual void execute()
	{
		LOG << this->get_type() << " executing"  << endl;
		mission_manager::get_intance()->set_general_mission(m_troop.front(), this);
		if (mission_manager::get_intance()->actioned_state() == false && mission_manager::get_intance()->active_general() == m_troop.front())
			event_arrived(new basic_mission_event(this));
	}

	virtual void event_arrived(mission_event *e)
	{
		LOG << this->get_type() << " event_arrived"  << endl;
		assert(e->get_type() == "basic_mission_event");
		basic_mission_event *bme = (basic_mission_event *)e;
		UserAPI &api = mission_manager::get_intance()->get_api();
		LandCity* city = api.GetCity(m_target);
		if (city->owner != -1)
		{
			if (city->owner == api.get_my_id())
			{
				LOG << get_type() << " occupied already" << endl;
				mission_manager::get_intance()->set_general_mission(m_troop.front(), 0);
				upcall_event(new occupy_completed_event(this, false, true));
			}
			else
			{
				LOG << get_type() << " occupied by enemy" << endl;
				mission_manager::get_intance()->set_general_mission(m_troop.front(), 0);
				upcall_event(new occupy_completed_event(this, false, false));
			}
			return;
		}

		Position start = api.GetCntArmy()->pos;

		if (api.HamDistance(start, m_target) == 0)
		{
			LOG << get_type() << " reach target" << endl;
			mission_manager::get_intance()->set_general_mission(m_troop.front(), 0);
			upcall_event(new occupy_completed_event(this, false, true));
			return;
		}

		mission_manager::get_intance()->set_actioned_state(true);
		api.Move(mission_manager::get_intance()->get_action_queue(), start, m_target);
	}

	virtual void cancel()
	{
		//	 do nothing
	}

	virtual std::string get_type() { return "occupy_empty_mission"; };

	Position m_target;
};